﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SafTypeRegistryCache.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.Saf.Registrations
{
    using System;
    using System.Collections;
    using System.ComponentModel;

    using Spring.Util;
    using Spring.Validation;

    /// <summary>
    /// Caches the Saf Registry entries for : 
    ///  - Converters
    ///  - Editors
    ///  - Validators
    /// </summary>
    [Serializable]
    public sealed class SafTypeRegistryCache
    {
        /// <summary>
        /// Name of the .Net config section that contains Spring.Net type aliases.
        /// </summary>
        private const string SafConvertersSectionName = "spring/safConverters";

        private const string SafEditorsSectionName = "spring/safEditors";

        private const string SafValdatorsSectionName = "spring/safValidators";


        private static IDictionary converters = new Hashtable();

        private static IDictionary validators = new Hashtable();

        private static IDictionary editors = new Hashtable();


        /// <summary>
        /// Registers standard and configured type converters.
        /// </summary>
        static SafTypeRegistryCache()
        {

            // read the converters, validators and editors in from the 
            // configuration files.
            lock (converters.SyncRoot)
            {
                //converters[typeof(string[])] = new GenericListOfStringConverter();

                // register user-defined type converters
                ConfigurationUtils.GetSection(SafConvertersSectionName);
            }

            lock (editors.SyncRoot)
            {
                //converters[typeof(string[])] = new GenericListOfStringConverter();

                // register user-defined type converters
                ConfigurationUtils.GetSection(SafEditorsSectionName);
            }

            lock (validators.SyncRoot)
            {
                //converters[typeof(string[])] = new GenericListOfStringConverter();

                // register user-defined type converters
                ConfigurationUtils.GetSection(SafValdatorsSectionName);
            }
        }

        /// <summary>
        /// Returns <see cref="TypeConverter"/> for the specified type.
        /// </summary>
        /// <param name="type">Type to get the converter for.</param>
        /// <returns>a type converter for the specified type.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="type"/> is <c>null</c>.</exception>
        public static TypeConverter GetConverter(Type type)
        {
            AssertUtils.ArgumentNotNull(type, "type");

            TypeConverter converter = (TypeConverter)converters[type];
            if (converter == null)
            {
                if (type.IsEnum)
                {
                    converter = new EnumConverter(type);
                }
                else
                {
                    converter = TypeDescriptor.GetConverter(type);
                }
            }

            return converter;
        }

        //public static SafEditor GetEditor(Type type)
        //{
        //    AssertUtils.ArgumentNotNull(type, "type");

        //    SafEditor editor = (SafEditor)editors[type];
        //    if (editor == null)
        //    {
        //        // provide default implementation
        //        editor = null;
        //    }

        //    return editor;
        //}

        public static ValidatorGroup GetValidator(Type type)
        {
            AssertUtils.ArgumentNotNull(type, "type");

            ValidatorGroup validator = (ValidatorGroup)editors[type];
            if (validator == null)
            {
                // provide default implementation
                validator = null;
            }

            return validator;
        }


        public static void RegisterConverter(Type type, SafConverter converter)
        {
            AssertUtils.ArgumentNotNull(type, "type");
            AssertUtils.ArgumentNotNull(converter, "converter");

            lock (converters.SyncRoot)
            {
                converters[type] = converter;
            }
        }


        //public static void RegisterEditor(Type type, SafEditor<T> editor)
        //{
        //    AssertUtils.ArgumentNotNull(type, "type");
        //    AssertUtils.ArgumentNotNull(editor, "editor");

        //    lock (editors.SyncRoot)
        //    {
        //        editors[type] = editor;
        //    }
        //}

        public static void RegisterValidator(Type type, SafValidator validator)
        {
            AssertUtils.ArgumentNotNull(type, "type");
            AssertUtils.ArgumentNotNull(validator, "validator");

            lock (validators.SyncRoot)
            {
                validators[type] = validator;
            }
        }



    }
}